import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class TimingTaskPool {

	TimingTaskLauncher timingTaskLauncher = new TimingTaskLauncher();

	public TimingTaskPool() throws InterruptedException {
		while (true) {
			// main loop here
			while (nextDueTask == null)
				wait();
			// then we have nextDueTask
			timingTaskLauncher.launch(nextDueTask);
			wait();
			
			if(nextDueTask.dueTime.getTime()<= new Date().getTime()){ //the task is done
				int i =timeSchedule.indexOf(nextDueTask);
				if(i==timeSchedule.size())
					nextDueTask=null;
				else
					nextDueTask=timeSchedule.get(i+1);
			}
			else if(nextDueTask==null){// nextDueTask has been canceled
				timingTaskLauncher.cancel();
			}
			else;	// nextDueTask has changed
		}
	}

	public synchronized void addTask(TimingTask task) {
		if (timeSchedule.size() == 0) {
			timeSchedule.add(task);
			if ((new Date()).before(task.dueTime))
				updateDueTask(task);
		} else {
			int i = 0;
			for (; i < timeSchedule.size(); i++)
				if (task.dueTime.before(timeSchedule.get(i).dueTime))
					break;
			timeSchedule.add(i, task);

			// update nextDueTask
			if ((new Date()).before(task.dueTime))
				if (nextDueTask == null)	
					updateDueTask(task);
				else if (task.dueTime.before(nextDueTask.dueTime))
					updateDueTask(task);

		}
	}

	private void updateDueTask(TimingTask task) {
		nextDueTask = task;
		notifyAll();
	}

	public synchronized void deleteTask(int taskIndex) {
		if (nextDueTask != null) {
			int i = timeSchedule.indexOf(nextDueTask);
			if (i == taskIndex)
				if (i != timeSchedule.size() - 1)
					updateDueTask(timeSchedule.get(taskIndex + 1));
				else
					deleteDueTask();
		}

		timeSchedule.remove(taskIndex);
	}

	private void deleteDueTask() {
		nextDueTask = null;
		notifyAll();
	}

	List<TimingTask> timeSchedule = Collections
			.synchronizedList(new LinkedList<TimingTask>());
	TimingTask nextDueTask = null;

	// test addTask and deletTask
	public static void main(String[] args) throws InterruptedException {
//		TimingTaskPool p = new TimingTaskPool();
//		Date timeNow = new Date();
//		System.out.println("time Now" + timeNow);
//		Date t1 = new Date(timeNow.getTime() + 10000);
//		Date t2 = new Date(timeNow.getTime() + 20000);
//		Date t3 = new Date(timeNow.getTime() + 30000);
//		Date t4 = new Date(timeNow.getTime() + 40000);
//		// p.addTask(new EmailTask(new Date(0)));
//		// p.addTask(new EmailTask(t3));
//		// p.addTask(new EmailTask(t1));
//		// p.addTask(new EmailTask(t2));
//		// p.addTask(new EmailTask(t4));
//		p.deleteTask(1);
//		p.deleteTask(p.timeSchedule.size() - 1);
//
//		for (int i = 0; i < p.timeSchedule.size(); i++)
//			System.out.println(p.timeSchedule.get(i).dueTime);

	}
}
